package com.zfl.vo;

import lombok.Data;
import java.io.Serializable;

/**
 * 统一接口返回结果类
 * 用于前后端交互时，统一响应格式（状态码 + 消息 + 数据）
 */
@Data
public class Result<T> implements Serializable {

    /**
     * 状态码：200=成功，400=参数错误，401=未授权，403=无权限，500=系统错误
     */
    private Integer code;

    /**
     * 提示消息（成功/失败的描述）
     */
    private String msg;

    /**
     * 返回数据（成功时携带业务数据，失败时可为null）
     */
    private T data;


    // -------------------------- 静态工厂方法（简化调用） --------------------------

    /**
     * 成功：无数据返回（仅返回状态码和默认成功消息）
     */
    public static <T> Result<T> success() {
        Result<T> result = new Result<>();
        result.setCode(200);
        result.setMsg("操作成功");
        return result;
    }

    /**
     * 成功：带数据返回（返回状态码、默认成功消息、业务数据）
     */
    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<>();
        result.setCode(200);
        result.setMsg("操作成功");
        result.setData(data);
        return result;
    }

    /**
     * 成功：自定义消息 + 数据返回（灵活场景使用）
     */
    public static <T> Result<T> success(String msg, T data) {
        Result<T> result = new Result<>();
        result.setCode(200);
        result.setMsg(msg);
        result.setData(data);
        return result;
    }

    /**
     * 失败：默认系统错误（返回默认500状态码 + 默认失败消息）
     */
    public static <T> Result<T> fail() {
        Result<T> result = new Result<>();
        result.setCode(500);
        result.setMsg("操作失败，请稍后重试");
        return result;
    }

    /**
     * 失败：自定义失败消息（默认500状态码）
     */
    public static <T> Result<T> fail(String msg) {
        Result<T> result = new Result<>();
        result.setCode(500);
        result.setMsg(msg);
        return result;
    }

    /**
     * 失败：自定义状态码 + 失败消息（精准场景使用，如401未授权、403无权限）
     */
    public static <T> Result<T> fail(Integer code, String msg) {
        Result<T> result = new Result<>();
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }

    /**
     * 失败：自定义状态码 + 消息 + 错误数据（极少场景使用，如返回错误详情）
     */
    public static <T> Result<T> fail(Integer code, String msg, T data) {
        Result<T> result = new Result<>();
        result.setCode(code);
        result.setMsg(msg);
        result.setData(data);
        return result;
    }
}